/**
 * 客户端测试1203接口脚本
 * 专注于测试：商店购买功能、物品数量叠加、数据结构验证
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置
const CONFIG = {
  server: {
    host: 'localhost',
    port: 3000,
    protocol: 'http'
  },

  // 测试用户信息
  testUser: {
    mobile: '17091271111',
    password: '123456',
    passwordHash: 'e10adc3949ba59abbe56e057f20f883e' // 123456的SHA256
  },

  // 测试角色信息
  testCharacter: {
    name: '测试角色',
    sex: 1, // 1:男, 0:女
    roleType: 1, // 1:武士, 2:文人, 3:异师
    headIndex: 2
  },

  // 测试购买物品信息
  testItems: [
    { id: 69, name: '测试物品1', count: 1, price: 100 },
    { id: 74, name: '测试物品2', count: 1, price: 200 },
    { id: 70, name: '测试物品3', count: 1, price: 500 }
  ]
};

class Code1203Tester {
  constructor() {
    this.token = null;
    this.userId = null;
    this.ws = null;
    this.characters = [];
    this.selectedCharacter = null;
    this.testResults = [];
    this.purchaseData = null;
    this.inventoryBefore = null;
    this.inventoryAfter = null;
  }

  // 运行完整测试流程
  async runTest () {
    console.log('🚀 开始客户端1203接口测试...\n');
    console.log('测试目标：HTTP登录 → WebSocket连接 → 选择角色 → 查询背包 → 购买物品 → 验证数量叠加 → 验证数据结构\n');

    try {
      // 1. HTTP登录
      await this.testHttpLogin();

      // 2. 建立WebSocket连接
      await this.testWebSocketConnection();

      // 3. 查询角色列表
      await this.testQueryCharacters();

      // 4. 如果没有角色，先创建角色
      if (this.characters.length === 0) {
        await this.testCreateCharacter();
        // 重新查询角色列表
        await this.testQueryCharacters();
      }

      // 5. 选择角色
      await this.testSelectCharacter();

      // 6. 查询购买前背包状态
      await this.testQueryInventoryBefore();

      // 7. 测试1203接口 - 购买物品
      await this.testCode1203Purchase();

      // 8. 测试1203接口 - 物品数量叠加
      await this.testCode1203ItemStacking();

      // 9. 查询购买后背包状态
      await this.testQueryInventoryAfter();

      // 10. 验证购买结果和数量叠加
      await this.validatePurchaseResults();

      // 11. 验证数据结构完整性
      await this.validateDataStructure();

      // 12. 断开连接
      await this.testDisconnect();

      // 输出测试结果
      this.printTestResults();

    } catch (error) {
      console.error('❌ 测试过程中发生错误:', error.message);
      this.addTestResult('整体测试', false, error.message);
    }
  }

  // 1. HTTP登录测试
  async testHttpLogin () {
    console.log('🔐 步骤1: HTTP登录测试...');

    try {
      // 首先尝试注册用户（如果不存在）
      await this.registerUser();

      // 执行登录
      const loginData = await this.makeHttpRequest('/user-service/user/login', 'POST', {
        mobile: CONFIG.testUser.mobile,
        pwd: CONFIG.testUser.passwordHash
      });

      if (loginData.code === 0 && loginData.data) {
        this.userId = loginData.data.userId;
        this.token = loginData.data.accessToken;

        console.log(`✅ 登录成功: userId=${this.userId}, token=${this.token.substring(0, 8)}...`);
        this.addTestResult('HTTP登录', true, `用户ID: ${this.userId}`);
      } else {
        throw new Error(`登录失败: ${loginData.msg || '未知错误'}`);
      }

    } catch (error) {
      console.log('❌ 登录失败:', error.message);
      this.addTestResult('HTTP登录', false, error.message);
      throw error;
    }
  }

  // 注册用户（如果不存在）
  async registerUser () {
    try {
      const res = await this.makeHttpRequest('/user-service/user/register', 'POST', {
        mobile: CONFIG.testUser.mobile,
        pwd: CONFIG.testUser.passwordHash,
        captcha: '123456' // 模拟验证码
      });
      console.log('📝 用户注册成功', res);
    } catch (error) {
      // 如果用户已存在，忽略错误
      if (error.message.includes('MOBILE_EXISTS') || error.message.includes('已存在')) {
        console.log('👤 用户已存在，跳过注册');
      } else {
        console.log('⚠️ 注册失败:', error.message);
      }
    }
  }

  // 2. WebSocket连接测试
  async testWebSocketConnection () {
    console.log('\n🔌 步骤2: WebSocket连接测试...');

    return new Promise((resolve, reject) => {
      try {
        const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
        this.ws = new WebSocket(wsUrl);

        this.ws.on('open', async () => {
          console.log('✅ WebSocket连接成功');
          this.addTestResult('WebSocket连接', true, '连接建立成功');

          // 设置消息监听器
          this.setupMessageHandler();

          // 等待连接完全稳定
          await this.delay(500);
          resolve();
        });

        this.ws.on('error', (error) => {
          console.log('❌ WebSocket连接失败:', error.message);
          this.addTestResult('WebSocket连接', false, error.message);
          reject(error);
        });

        this.ws.on('close', () => {
          console.log('🔌 WebSocket连接已关闭');
        });

        // 连接超时
        setTimeout(() => {
          if (this.ws.readyState === WebSocket.CONNECTING) {
            this.ws.close();
            reject(new Error('连接超时'));
          }
        }, 10000);

      } catch (error) {
        reject(error);
      }
    });
  }

  // 设置消息处理器
  setupMessageHandler () {
    this.ws.on('message', (data) => {
      try {
        const message = JSON.parse(data.toString());
        console.log('📨 收到消息:', JSON.stringify(message, null, 2));

        // 根据act_id处理不同类型的响应
        this.handleWebSocketResponse(message);

      } catch (error) {
        console.error('❌ 消息解析失败:', error.message);
      }
    });
  }

  // 处理WebSocket响应
  handleWebSocketResponse (message) {
    const { act_id, code, roleList, roleCount, data, msg } = message;

    switch (act_id) {
      case 3: // 查询角色列表响应
        if (roleList && Array.isArray(roleList)) {
          this.characters = roleList;
          console.log(`📋 获取到${roleCount || roleList.length}个角色`);
        }
        break;

      case 4: // 角色选择响应
        if (code === 0) {
          console.log('🎯 角色选择成功');
        }
        break;

      case 5: // 角色创建响应（兼容格式）
        if (code === 0) {
          console.log('🆕 角色创建成功');
        }
        break;

      case 390: // 角色创建响应（标准指令）
        if (code === 0) {
          console.log('🆕 角色创建成功');
        }
        break;

      case 1203: // 商店购买响应
        this.purchaseData = {
          act_id: message.act_id,
          code: message.code,
          success: message.success,
          goods: message.goods,
          message: message.message,
          timestamp: new Date().toISOString()
        };
        console.log(`🛒 购买响应数据接收:`, JSON.stringify(this.purchaseData, null, 2));
        break;

      case 1425: // 背包杂物查询响应
        if (code === 0) {
          this.inventoryAfter = {
            act_id: message.act_id,
            code: message.code,
            data: message.data || [],
            timestamp: new Date().toISOString()
          };
          console.log(`📦 背包查询响应数据接收:`, JSON.stringify(this.inventoryAfter, null, 2));
        }
        break;

      default:
        // 记录其他消息但不处理
        break;
    }
  }

  // 3. 查询角色列表
  async testQueryCharacters () {
    console.log('\n📋 步骤3: 查询角色列表...');

    return new Promise(async (resolve) => {
      if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
        this.addTestResult('查询角色列表', false, 'WebSocket未连接');
        resolve();
        return;
      }

      // 等待WebSocket连接稳定
      await this.delay(1000);

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 3) {
            this.ws.removeListener('message', responseHandler);

            if (message.roleList && Array.isArray(message.roleList)) {
              this.characters = message.roleList;
              console.log(`✅ 查询成功，共${message.roleCount || message.roleList.length}个角色`);
              this.addTestResult('查询角色列表', true, `获取${this.characters.length}个角色`);
            } else {
              // 即使没有角色，也算查询成功
              this.characters = [];
              console.log('✅ 查询成功，暂无角色');
              this.addTestResult('查询角色列表', true, '获取0个角色');
            }
            resolve();
          }
        } catch (error) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('查询角色列表', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送查询角色列表请求
      this.ws.send(JSON.stringify({
        c: 3,
        d: null
      }));

      // 设置超时
      setTimeout(() => {
        this.ws.removeListener('message', responseHandler);
        this.addTestResult('查询角色列表', false, '请求超时');
        resolve();
      }, 10000);
    });
  }

  // 4. 创建角色测试
  async testCreateCharacter () {
    console.log('\n🆕 步骤4: 创建角色测试...');

    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.addTestResult('创建角色', false, 'WebSocket未连接');
      return;
    }

    return new Promise((resolve) => {
      let responseReceived = false;
      let retryCount = 0;
      const maxRetries = 2;

      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          console.log(`📨 收到创建角色响应:`, JSON.stringify(message, null, 2));

          if (message.act_id === 5 || message.act_id === 390) { // 兼容格式或标准指令
            this.ws.removeListener('message', responseHandler);
            responseReceived = true;

            if (message.code === 0) {
              console.log('✅ 角色创建成功');
              this.addTestResult('创建角色', true, '角色创建成功');

              // 等待一段时间让服务器处理角色创建
              setTimeout(() => {
                resolve();
              }, 2000);
            } else {
              const errorMsg = message.msg || '未知错误';
              console.log(`❌ 角色创建失败: ${errorMsg}`);

              // 如果是角色名重复，尝试使用不同的名字
              if (errorMsg.includes('重复') || errorMsg.includes('已存在') || errorMsg.includes('DUPLICATE')) {
                if (retryCount < maxRetries) {
                  retryCount++;
                  const newName = `${CONFIG.testCharacter.name}_${Date.now()}`;
                  console.log(`🔄 角色名重复，尝试使用新名字: ${newName}`);

                  // 重新发送创建角色请求
                  setTimeout(() => {
                    this.createCharacterWithName(newName, resolve);
                  }, 1000);
                  return;
                }
              }

              this.addTestResult('创建角色', false, errorMsg);
              resolve();
            }
          }
        } catch (error) {
          console.error('❌ 创建角色响应解析失败:', error.message);
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('创建角色', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送创建角色请求
      this.createCharacterWithName(CONFIG.testCharacter.name, resolve);

      // 设置超时
      setTimeout(() => {
        if (!responseReceived) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('创建角色', false, '请求超时');
          resolve();
        }
      }, 15000);
    });
  }

  // 使用指定名字创建角色
  createCharacterWithName (name, resolve) {
    const createData = {
      c: 5, // 兼容格式
      d: {
        name: name,
        sex: CONFIG.testCharacter.sex,
        roleType: CONFIG.testCharacter.roleType,
        headIndex: CONFIG.testCharacter.headIndex
      }
    };

    console.log(`📤 发送创建角色请求:`, JSON.stringify(createData, null, 2));
    this.ws.send(JSON.stringify(createData));
  }

  // 5. 选择角色
  async testSelectCharacter () {
    console.log('\n🎯 步骤5: 选择角色...');

    if (this.characters.length === 0) {
      console.log('⚠️ 没有可选择的角色');
      this.addTestResult('选择角色', false, '没有可用角色');
      return;
    }

    return new Promise((resolve) => {
      if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
        this.addTestResult('选择角色', false, 'WebSocket未连接');
        resolve();
        return;
      }

      // 选择第一个角色
      const targetCharacter = this.characters[0];

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 4) {
            this.ws.removeListener('message', responseHandler);

            if (message.code === 0) {
              this.selectedCharacter = targetCharacter;
              console.log(`✅ 角色选择成功: ${targetCharacter.name} (ID: ${targetCharacter.id})`);
              this.addTestResult('选择角色', true, `选择角色: ${targetCharacter.name}`);

              // 等待服务器处理角色选择
              setTimeout(() => {
                resolve();
              }, 2000);
            } else {
              console.log(`❌ 角色选择失败: ${message.msg || '未知错误'}`);
              this.addTestResult('选择角色', false, message.msg || '选择失败');
              resolve();
            }
          }
        } catch (error) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('选择角色', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送选择角色请求
      this.ws.send(JSON.stringify({
        c: 4,
        d: {
          characterId: targetCharacter.id
        }
      }));

      // 设置超时
      setTimeout(() => {
        this.ws.removeListener('message', responseHandler);
        this.addTestResult('选择角色', false, '请求超时');
        resolve();
      }, 10000);
    });
  }

  // 6. 查询购买前背包状态
  async testQueryInventoryBefore () {
    console.log('\n📦 步骤6: 查询购买前背包状态...');

    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.addTestResult('查询购买前背包', false, 'WebSocket未连接');
      return;
    }

    return new Promise((resolve) => {
      let responseReceived = false;

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 1425) {
            this.ws.removeListener('message', responseHandler);
            responseReceived = true;

            if (message.code === 0) {
              this.inventoryBefore = {
                act_id: message.act_id,
                code: message.code,
                data: message.data || [],
                timestamp: new Date().toISOString()
              };
              console.log('✅ 购买前背包查询成功');
              console.log(`📦 背包物品数量: ${this.inventoryBefore.data.length}`);
              this.addTestResult('查询购买前背包', true, `背包物品数量: ${this.inventoryBefore.data.length}`);
            } else {
              console.log(`❌ 购买前背包查询失败: ${message.msg || '未知错误'}`);
              this.addTestResult('查询购买前背包', false, message.msg || '查询失败');
            }
            resolve();
          }
        } catch (error) {
          console.error('❌ 购买前背包查询响应解析失败:', error.message);
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('查询购买前背包', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送背包查询请求
      const requestData = {
        c: 1425,
        d: { pageNum: 0 }
      };

      console.log(`📤 发送背包查询请求:`, JSON.stringify(requestData, null, 2));
      this.ws.send(JSON.stringify(requestData));

      // 设置超时
      setTimeout(() => {
        if (!responseReceived) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('查询购买前背包', false, '请求超时');
          resolve();
        }
      }, 10000);
    });
  }

  // 7. 测试1203接口 - 购买物品
  async testCode1203Purchase () {
    console.log('\n🛒 步骤7: 测试1203接口 - 购买物品...');

    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.addTestResult('1203接口测试(购买物品)', false, 'WebSocket未连接');
      return;
    }

    return new Promise((resolve) => {
      let responseReceived = false;

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 1203) {
            this.ws.removeListener('message', responseHandler);
            responseReceived = true;

            if (message.code === 0 || message.success) {
              console.log('✅ 1203购买接口调用成功');
              console.log(`🛒 购买物品: ${message.goods?.name || '未知'}, 数量: ${message.goods?.count || 0}`);
              this.addTestResult('1203接口测试(购买物品)', true, `购买成功: ${message.goods?.name || '未知'}`);
            } else {
              console.log(`❌ 1203购买接口调用失败: ${message.msg || '未知错误'}`);
              this.addTestResult('1203接口测试(购买物品)', false, message.msg || '购买失败');
            }
            resolve();
          }
        } catch (error) {
          console.error('❌ 1203购买接口响应解析失败:', error.message);
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('1203接口测试(购买物品)', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送1203请求 - 购买物品
      const testItem = CONFIG.testItems[0];
      const requestData = {
        c: 1203,
        d: {
          gid: testItem.id,
          count: testItem.count
        }
      };

      console.log(`📤 发送1203购买请求:`, JSON.stringify(requestData, null, 2));
      this.ws.send(JSON.stringify(requestData));

      // 设置超时
      setTimeout(() => {
        if (!responseReceived) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('1203接口测试(购买物品)', false, '请求超时');
          resolve();
        }
      }, 10000);
    });
  }



  // 8. 测试1203接口 - 物品数量叠加
  async testCode1203ItemStacking () {
    console.log('\n🔄 步骤8: 测试1203接口 - 物品数量叠加...');

    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.addTestResult('1203接口测试(物品叠加)', false, 'WebSocket未连接');
      return;
    }

    return new Promise((resolve) => {
      let responseReceived = false;

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 1203) {
            this.ws.removeListener('message', responseHandler);
            responseReceived = true;

            if (message.code === 0 || message.success) {
              console.log('✅ 1203物品叠加测试成功');
              console.log(`🔄 叠加购买物品: ${message.goods?.name || '未知'}, 数量: ${message.goods?.count || 0}`);
              this.addTestResult('1203接口测试(物品叠加)', true, `叠加购买成功: ${message.goods?.name || '未知'}`);
            } else {
              console.log(`❌ 1203物品叠加测试失败: ${message.msg || '未知错误'}`);
              this.addTestResult('1203接口测试(物品叠加)', false, message.msg || '叠加购买失败');
            }
            resolve();
          }
        } catch (error) {
          console.error('❌ 1203物品叠加测试响应解析失败:', error.message);
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('1203接口测试(物品叠加)', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送1203请求 - 购买相同物品进行叠加测试
      const testItem = CONFIG.testItems[0]; // 使用第一个物品
      const requestData = {
        c: 1203,
        d: {
          gid: testItem.id,
          count: 2 // 再次购买2个，测试叠加
        }
      };

      console.log(`📤 发送1203物品叠加测试请求:`, JSON.stringify(requestData, null, 2));
      this.ws.send(JSON.stringify(requestData));

      // 设置超时
      setTimeout(() => {
        if (!responseReceived) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('1203接口测试(物品叠加)', false, '请求超时');
          resolve();
        }
      }, 10000);
    });
  }

  // 9. 查询购买后背包状态
  async testQueryInventoryAfter () {
    console.log('\n📦 步骤9: 查询购买后背包状态...');

    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.addTestResult('查询购买后背包', false, 'WebSocket未连接');
      return;
    }

    return new Promise((resolve) => {
      let responseReceived = false;

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 1425) {
            this.ws.removeListener('message', responseHandler);
            responseReceived = true;

            if (message.code === 0) {
              this.inventoryAfter = {
                act_id: message.act_id,
                code: message.code,
                data: message.data || [],
                timestamp: new Date().toISOString()
              };
              console.log('✅ 购买后背包查询成功');
              console.log(`📦 背包物品数量: ${this.inventoryAfter.data.length}`);
              this.addTestResult('查询购买后背包', true, `背包物品数量: ${this.inventoryAfter.data.length}`);
            } else {
              console.log(`❌ 购买后背包查询失败: ${message.msg || '未知错误'}`);
              this.addTestResult('查询购买后背包', false, message.msg || '查询失败');
            }
            resolve();
          }
        } catch (error) {
          console.error('❌ 购买后背包查询响应解析失败:', error.message);
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('查询购买后背包', false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 等待一段时间让购买操作完成
      setTimeout(() => {
        // 发送背包查询请求
        const requestData = {
          c: 1425,
          d: { pageNum: 0 }
        };

        console.log(`📤 发送购买后背包查询请求:`, JSON.stringify(requestData, null, 2));
        this.ws.send(JSON.stringify(requestData));
      }, 2000);

      // 设置超时
      setTimeout(() => {
        if (!responseReceived) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult('查询购买后背包', false, '请求超时');
          resolve();
        }
      }, 15000);
    });
  }

  // 10. 验证购买结果和数量叠加
  async validatePurchaseResults () {
    console.log('\n🔍 步骤10: 验证购买结果和数量叠加...');

    if (!this.inventoryBefore || !this.inventoryAfter) {
      console.log('⚠️ 没有背包数据可供验证');
      this.addTestResult('购买结果验证', false, '无背包数据可供验证');
      return;
    }

    const beforeItems = this.inventoryBefore.data || [];
    const afterItems = this.inventoryAfter.data || [];

    console.log(`📊 购买前背包物品数量: ${beforeItems.length}`);
    console.log(`📊 购买后背包物品数量: ${afterItems.length}`);

    // 检查是否有新增物品
    if (afterItems.length >= beforeItems.length) {
      console.log('✅ 背包物品数量验证通过');
      this.addTestResult('购买结果验证', true, `背包物品数量: ${beforeItems.length} → ${afterItems.length}`);

      // 检查物品数量叠加
      const stackingResults = this.checkItemStacking(beforeItems, afterItems);
      if (stackingResults.isValid) {
        console.log('✅ 物品数量叠加验证通过');
        this.addTestResult('物品叠加验证', true, stackingResults.message);
      } else {
        console.log('⚠️ 物品数量叠加验证失败');
        this.addTestResult('物品叠加验证', false, stackingResults.message);
      }
    } else {
      console.log('❌ 背包物品数量验证失败');
      this.addTestResult('购买结果验证', false, '背包物品数量异常减少');
    }
  }

  // 检查物品数量叠加
  checkItemStacking (beforeItems, afterItems) {
    const beforeMap = new Map();
    const afterMap = new Map();

    // 构建购买前的物品映射
    beforeItems.forEach(item => {
      beforeMap.set(item.id, item.num || 0);
    });

    // 构建购买后的物品映射
    afterItems.forEach(item => {
      afterMap.set(item.id, item.num || 0);
    });

    let stackingFound = false;
    let stackingDetails = [];

    // 检查每个物品的数量变化
    afterMap.forEach((afterNum, itemId) => {
      const beforeNum = beforeMap.get(itemId) || 0;
      if (afterNum > beforeNum) {
        stackingFound = true;
        stackingDetails.push(`物品${itemId}: ${beforeNum} → ${afterNum} (+${afterNum - beforeNum})`);
      }
    });

    if (stackingFound) {
      return {
        isValid: true,
        message: `发现${stackingDetails.length}个物品数量增加: ${stackingDetails.join(', ')}`
      };
    } else {
      return {
        isValid: false,
        message: '未发现物品数量叠加'
      };
    }
  }

  // 11. 验证数据结构完整性
  async validateDataStructure () {
    console.log('\n🔍 步骤11: 验证数据结构完整性...');

    if (!this.purchaseData) {
      console.log('⚠️ 没有购买数据可供验证');
      this.addTestResult('数据结构验证', false, '无购买数据可供验证');
      return;
    }

    const purchase = this.purchaseData;
    let validFields = 0;
    const requiredFields = ['act_id', 'code', 'success', 'goods', 'message'];

    console.log(`📊 开始验证购买响应数据结构...`);

    requiredFields.forEach(field => {
      if (field in purchase) {
        validFields++;
      } else {
        console.log(`❌ 缺失字段: ${field}`);
      }
    });

    // 验证goods字段的子字段
    if (purchase.goods) {
      const goodsFields = ['id', 'name', 'count', 'price', 'totalPrice'];
      goodsFields.forEach(field => {
        if (field in purchase.goods) {
          validFields++;
        } else {
          console.log(`❌ goods字段缺失子字段: ${field}`);
        }
      });
    }

    const totalFields = requiredFields.length + (purchase.goods ? 5 : 0);
    console.log(`📊 数据结构验证结果: ${validFields}/${totalFields} 个字段通过验证`);

    if (validFields === totalFields) {
      console.log('✅ 购买响应数据结构验证通过');
      this.addTestResult('数据结构验证', true, `所有${totalFields}个字段验证通过`);
    } else {
      console.log(`⚠️ 购买响应数据结构验证失败: ${totalFields - validFields}个字段有问题`);
      this.addTestResult('数据结构验证', false, `${validFields}/${totalFields}个字段验证通过`);
    }
  }

  // 12. 断开连接
  async testDisconnect () {
    console.log('\n🔌 步骤12: 断开WebSocket连接...');
    if (this.ws) {
      this.ws.close();
    }
    this.addTestResult('断开连接', true, '连接已断开');
  }

  // 添加测试结果
  addTestResult (testName, success, message) {
    this.testResults.push({
      test: testName,
      success: success,
      message: message,
      timestamp: new Date().toISOString()
    });
  }

  // 打印测试结果
  printTestResults () {
    console.log('\n📊 测试结果汇总:');
    console.log('='.repeat(50));

    let successCount = 0;
    let totalCount = this.testResults.length;

    this.testResults.forEach((result, index) => {
      const status = result.success ? '✅' : '❌';
      console.log(`${index + 1}. ${status} ${result.test}: ${result.message}`);
      if (result.success) successCount++;
    });

    console.log('='.repeat(50));
    console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

    if (successCount === totalCount) {
      console.log('🎉 所有测试通过！');
    } else {
      console.log('⚠️  部分测试失败，请检查日志');
    }

    // 输出购买数据分析
    if (this.purchaseData) {
      console.log('\n🛒 购买响应数据分析:');
      console.log('='.repeat(50));
      console.log(`响应状态: ${this.purchaseData.success ? '成功' : '失败'}`);
      if (this.purchaseData.goods) {
        console.log(`购买物品: ${this.purchaseData.goods.name}`);
        console.log(`购买数量: ${this.purchaseData.goods.count}`);
        console.log(`物品价格: ${this.purchaseData.goods.price}`);
        console.log(`总价格: ${this.purchaseData.goods.totalPrice}`);
      }
      console.log(`响应消息: ${this.purchaseData.message}`);
    }

    // 输出背包变化分析
    if (this.inventoryBefore && this.inventoryAfter) {
      console.log('\n📦 背包变化分析:');
      console.log('='.repeat(50));
      console.log(`购买前物品数量: ${this.inventoryBefore.data.length}`);
      console.log(`购买后物品数量: ${this.inventoryAfter.data.length}`);
      console.log(`物品数量变化: ${this.inventoryAfter.data.length - this.inventoryBefore.data.length}`);
    }
  }

  // HTTP请求工具方法
  async makeHttpRequest (path, method = 'GET', data = null) {
    return new Promise((resolve, reject) => {
      const options = {
        hostname: CONFIG.server.host,
        port: CONFIG.server.port,
        path: path,
        method: method,
        headers: {
          'Content-Type': 'application/json',
        }
      };

      if (data) {
        const postData = JSON.stringify(data);
        options.headers['Content-Length'] = Buffer.byteLength(postData);
      }

      const req = http.request(options, (res) => {
        let body = '';

        res.on('data', (chunk) => {
          body += chunk;
        });

        res.on('end', () => {
          try {
            const responseData = JSON.parse(body);
            if (res.statusCode >= 200 && res.statusCode < 300) {
              resolve(responseData);
            } else {
              reject(new Error(`HTTP ${res.statusCode}: ${responseData.message || body}`));
            }
          } catch (error) {
            if (res.statusCode >= 200 && res.statusCode < 300) {
              resolve(body);
            } else {
              reject(new Error(`HTTP ${res.statusCode}: ${body}`));
            }
          }
        });
      });

      req.on('error', (error) => {
        reject(error);
      });

      if (data) {
        req.write(JSON.stringify(data));
      }

      req.end();
    });
  }

  // 延迟函数
  async delay (ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// 运行测试
async function main () {
  const tester = new Code1203Tester();
  await tester.runTest();
}

// 如果直接运行此脚本
if (require.main === module) {
  main().catch((error) => {
    console.error('💥 测试脚本执行失败:', error.message);
    process.exit(1);
  });
}

module.exports = Code1203Tester; 